package com.ziyucoding.springboot.labs.lab3.sca.rocketmqdemo.dtd.order.listener;

import com.alibaba.fastjson.JSONObject;
import com.ziyucoding.springboot.labs.lab3.sca.rocketmqdemo.dtd.order.dto.OrderDTO;
import com.ziyucoding.springboot.labs.lab3.sca.rocketmqdemo.dtd.order.message.OrderMessage;
import com.ziyucoding.springboot.labs.lab3.sca.rocketmqdemo.dtd.order.service.OrderService;
import com.ziyucoding.springboot.labs.lab3.sca.rocketmqdemo.dtd.order.service.TransactionLogService;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

/**
 * 订单事务监听器
 *
 * @author ziyucoding
 * @date 2023-04-02
 **/
@RocketMQTransactionListener(txProducerGroup = "order_trans_producer_group")
public class OrderTransactionListener implements RocketMQLocalTransactionListener {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OrderService orderService;

    @Autowired
    private TransactionLogService transactionLogService;

    /**
     * 执行本地事务
     *
     * @param message
     * @param o
     * @return RocketMQLocalTransactionState
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(org.springframework.messaging.Message message, Object o) {
        logger.info("开始执行本地事务....");
        RocketMQLocalTransactionState state;
        try {
            // 从消息 Header 中解析到 order 参数，并使用 JSON 反序列化
            OrderDTO order = JSONObject.parseObject(message.getHeaders().get("order", String.class),
                    OrderDTO.class);
            String transactionId = (String) message.getHeaders().get("rocketmq_TRANSACTION_ID");
            orderService.createOrder(order, transactionId);
            state = RocketMQLocalTransactionState.COMMIT;
            logger.info("本地事务已提交。{}", transactionId);
        } catch (Exception e) {
            logger.info("执行本地事务失败。{}", e);
            state = RocketMQLocalTransactionState.ROLLBACK;
        }
        return state;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(org.springframework.messaging.Message message) {
        String transactionId = (String) message.getHeaders().get("rocketmq_TRANSACTION_ID");
        logger.info("开始回查本地事务状态。{}", transactionId);
        RocketMQLocalTransactionState state;
        if (transactionLogService.count(transactionId) > 0) {
            state = RocketMQLocalTransactionState.COMMIT;
        } else {
            // 将其设置为未知状态
            state = RocketMQLocalTransactionState.UNKNOWN;
        }
        logger.info("结束本地事务状态查询：{}", state);
        return state;
    }

}
